#ifndef LIBRARY
#define LIBRARY
#include <iostream>
#include <vector>
#include <string>
#include <ctime>

enum ConditionType {Author, Title, Isbn, Name, Address, MemberType, All};

class Member;

class Book{
private:
	std::string author;
	std::string title;
	std::string publisher;
	int year;
	int issue;
	std::string ISBN;
	bool available;
	time_t limit;
	mutable std::string datecache;
	const Member* at;
	std::string id;
public:
	Book(const std::string&, const std::string&, const std::string&, int, int, const std::string&);
	void write(std::ostream&)const;
	bool LendAt(const Member*, time_t);
	bool Back(const Member*,bool);
	std::string getID()const{return id;}
	void setID(const std::string& s){id=s;}
	std::string getData(ConditionType)const;
};

class Member{
protected:
	std::string name;
	std::string address;
	std::string mail;
	std::vector<Book*> books;
	std::string id;
public:
	Member(const std::string&, const std::string&, const std::string&, const std::string&);
	virtual ~Member();
	virtual void write(std::ostream& out=std::cout)const;
	void writeBooks()const;
	virtual bool LendTo(Book*)=0;
	void Back(const Book*);
	virtual time_t limit()const=0;
	std::string getID()const{return id;}
	void setID(const std::string& s){id=s;}
	std::string getData(ConditionType)const;
	virtual std::string getType()const=0;
	void setData(int, const std::string&);
	void ClearBooks();
};

class Librarian{
private:
	std::string fnev;
	std::string pwd;
public:
	Librarian(const std::string&, const std::string&);
	bool Checkpwd(const std::string&, const std::string&);
	void write(std::ostream&)const;
};

class Library{
private:
	std::vector<Book*> books;
	std::vector<Member*> members;
	std::vector<Librarian*> librarians;
	int userID;
public:
	Library();
	~Library();
	void NewMember(Member*, int);
	void NewBook(const Book&, int);
	void ListMembers(ConditionType, const std::string&)const;
	void ListBooks(ConditionType, const std::string&)const;
	void DeleteMember(const std::string&);
	void DeleteBook(const std::string&);
	void ModifyMember(const std::string&, int, const std::string&);
	void ViewMember(const std::string&)const;
	void Lend(const std::string&, const std::string&);
	void Back(const std::string&, const std::string&);
	void SignIn();
	void Logout();
	void LoadData();
	void SaveData();
};

class Student: public Member{
public:
	Student(const std::string& a, const std::string& b, const std::string& c, const std::string& d):Member(a,b,c,d){}
	void write(std::ostream&)const;
	bool LendTo(Book*);
	time_t limit()const{return time(NULL)+60*24*60*60;}
	std::string getType()const{return "hallgato";}
};

class Professor: public Member{
public:
	Professor(const std::string& a, const std::string& b, const std::string& c, const std::string& d):Member(a,b,c,d){}
	void write(std::ostream&)const;
	bool LendTo(Book*);
	time_t limit()const{return time(NULL)+365*24*60*60;}
	std::string getType()const{return "oktato";}
};

class Student2: public Member{
public:
	Student2(const std::string& a, const std::string& b, const std::string& c, const std::string& d):Member(a,b,c,d){}
	void write(std::ostream&)const;
	bool LendTo(Book*);
	time_t limit()const{return time(NULL)+30*24*60*60;}
	std::string getType()const{return "mas egyetemrol";}
};

class Other: public Member{
public:
	Other(const std::string& a, const std::string& b, const std::string& c, const std::string& d):Member(a,b,c,d){}
	void write(std::ostream&)const;
	bool LendTo(Book*);
	time_t limit()const{return time(NULL)+14*24*60*60;}
	std::string getType()const{return "egyeb";}
};



#endif
